{-# LANGUAGE EmptyDataDecls             #-}
{-# OPTIONS -Wall #-}

--------------------------------------------------------------------------------
-- |
-- Module      :  Orca.Csound.Zak
-- Copyright   :  (c) Stephen Tetley 2013
-- License     :  BSD3
--
-- Maintainer  :  stephen.tetley@gmail.com
-- Stability   :  unstable
-- Portability :  GHC
--
-- Zak patch system.
-- 
--------------------------------------------------------------------------------

module Orca.Csound.Zak
  (


    ZakIx
  , zakIx
 
--  , zakinit
  , cs_ziw
  , cs_zkw
  , cs_zaw

  , cs_ziwm
  , cs_ziwm_
  , cs_zkwm
  , cs_zkwm_
  , cs_zawm
  , cs_zawm_

  , cs_zir
  , cs_zkr
  , cs_zar
  , cs_zarg
  , cs_zkmod
  , cs_zamod
  , cs_zkcl
  , cs_zacl

  ) where

import Orca.Csound.Monad
import Orca.Csound.Syntax



data TokZakIx

type ZakIx = PExpr TokZakIx


-- | Constructor for Zak index.
--
zakIx :: IInt -> ZakIx
zakIx ma = PExpr $ getPExpr ma



{-

-- | Initialize. 
--
-- Note - this is a orchestra level (not instrument level) opcode 
-- so potentially it will be removed.
-- 
-- > zakinit : isizea * isizek -> ()
--
zakinit :: IInt -> IInt -> Orch ()
zakinit isizea isizek = 
    globalInvoke (primId "zakinit") [getPExpr isizea, getPExpr isizek]

-}


-- | Writes zak variable at i-rate without mixing.
--
-- > ziw : isig * indx -> ()
--
cs_ziw :: IFloat -> ZakIx -> Orca ()
cs_ziw isig indx = 
    genOpcode0 "ziw" [ getPExpr isig, getPExpr indx ]


-- Note - somewhat /contradictory/ type.
--
-- > zkw : ksig *  kndx -> ()
--
-- @kndx@ is a K Rate integer, this implies we have more K Rate 
-- /types/ than just a KSignal. Maybe types should be a product
-- of Type (in the ususal Haskell sense) and Rate.
-- 
-- Idiomatically, @kndx@ is usually assigned to a pfield 
-- (out chan) and is constant for the length of the note.
--


-- | Writes zak variable at k-rate without mixing.
--
-- > zkw : ksig * kndx -> ()
--
cs_zkw :: KSig -> ZakIx -> Orca ()
cs_zkw ksig kndx = 
    genOpcode0 "ziw" [ getPExpr ksig, getPExpr kndx ]



-- | Writes zak variable at a-rate without mixing.
--
-- > zkw : asig * kndx -> ()
--
cs_zaw :: ASig -> ZakIx -> Orca ()
cs_zaw asig kndx = 
    genOpcode0 "zaw" [ getPExpr asig, getPExpr kndx ]


-- | Writes zak variable at i-rate with mixing.
--
-- > ziw : isig * indx -> ()
--
cs_ziwm :: IFloat -> ZakIx -> Orca ()
cs_ziwm isig indx = 
    genOpcode0 "zwim" [ getPExpr isig, getPExpr indx ]


-- | Writes zak variable at i-rate with mixing.
--
-- > ziw : isig * indx * imix -> ()
--
-- (Needs checking that Bool istranslated to 0 or 1).
--
cs_ziwm_ :: IFloat -> ZakIx -> IBool -> Orca ()
cs_ziwm_ isig indx imix = 
    genOpcode0 "zwim" [ getPExpr isig, getPExpr indx
                      , getPExpr imix ]




-- | Writes zak variable at k-rate with mixing.
--
-- > ziw : ksig * kndx -> ()
--
cs_zkwm :: KSig -> ZakIx -> Orca ()
cs_zkwm ksig kndx = 
    genOpcode0 "zwkm" [ getPExpr ksig, getPExpr kndx ]


-- | Writes zak variable at k-rate with mixing.
--
-- > ziw : ksig * kndx * imix -> ()
--
cs_zkwm_ :: KSig -> ZakIx -> IBool -> Orca ()
cs_zkwm_ ksig kndx kmix = 
    genOpcode0 "zwkm" [ getPExpr ksig, getPExpr kndx 
                      , getPExpr kmix ]



-- | Writes zak variable at a-rate with mixing.
--
-- > zawm : asig * kndx -> ()
--
cs_zawm :: KSig -> ZakIx -> Orca ()
cs_zawm asig kndx = 
    genOpcode0 "zawm" [ getPExpr asig, getPExpr kndx ]


-- | Writes zak variable at a-rate with mixing.
--
-- > ziw : asig * kndx * kmix -> ()
--
cs_zawm_ :: KSig -> ZakIx -> IBool -> Orca ()
cs_zawm_ asig kndx kmix = 
    genOpcode0 "zawm" [ getPExpr asig, getPExpr kndx
                      , getPExpr kmix ]
 


-- | Read a zak variable at i-rate.
--
-- > zir : indx -> ir
--
cs_zir :: ZakIx -> Orca ISig
cs_zir indx = 
    genOpcode1 I_RATE "zir" [ getPExpr indx ]


-- | Read a zak variable at k-rate.
--
-- > zkr : kndx -> kres
--
cs_zkr :: ZakIx -> Orca KSig
cs_zkr kndx = 
    genOpcode1 K_RATE "zkr" [ getPExpr kndx ]


-- | Read a zak variable at a-rate.
--
-- > zar : kndx -> ares
--
cs_zar :: ZakIx -> Orca ASig
cs_zar kndx = 
    genOpcode1 A_RATE "zar" [ getPExpr kndx ]


-- | Read a zak variable at a-rate add some gain.
--
-- > zarg : kndx * kgain -> ares
--
cs_zarg :: ZakIx -> KSig -> Orca ASig
cs_zarg kndx kgain = 
    genOpcode1 A_RATE "zarg" [ getPExpr kndx, getPExpr kgain ]


-- | Modulate one k-rate signal by another.
--
-- > zkmod : ksig * kzkmod -> kres
--
cs_zkmod :: KSig -> ZakIx -> Orca KSig
cs_zkmod ksig kzkmod = 
    genOpcode1 K_RATE "zkmod" [ getPExpr ksig, getPExpr kzkmod ]


-- | Modulate one a-rate signal by another.
--
-- > zamod : asig * kzamod -> ares
--
-- Note - zakIx can be negated to mean multiplicative modulation.
-- This is /obscure/ - potentially we need a more Haskell-like 
-- API.
--
cs_zamod :: ASig -> ZakIx -> Orca ASig
cs_zamod asig kzamod = 
    genOpcode1 A_RATE "zamod" [ getPExpr asig, getPExpr kzamod ]


-- | Clear range of zak variables - k-rate.
--
-- > zkcl : kfirst * klast -> ()
--
cs_zkcl  :: ZakIx -> ZakIx -> Orca ()
cs_zkcl kfirst klast = 
    genOpcode0 "zkcl" [ getPExpr kfirst, getPExpr klast ]


-- | Clear range of zak variables - k-rate.
--
-- > zacl : kfirst * klast -> ()
-- 
cs_zacl  :: ZakIx -> ZakIx -> Orca ()
cs_zacl kfirst klast = 
    genOpcode0 "zacl" [ getPExpr kfirst, getPExpr klast ]

